package com.xbongbong.saas.model.impl;

import com.xbongbong.paas.constant.PaasConstant;
import com.xbongbong.paas.domain.entity.PaasFormDataEntity;
import com.xbongbong.paas.elasticsearch.model.PaasEsModel;
import com.xbongbong.paas.elasticsearch.pojo.dto.InsertDTO;
import com.xbongbong.paas.enums.DelEnum;
import com.xbongbong.paas.enums.IndexTypeEnum;
import com.xbongbong.paas.help.subform.TransferSubFormHelper;
import com.xbongbong.paas.pojo.dto.SaasFormSaveDTO;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.CollectionsUtil;
import com.xbongbong.paas.toolbox.util.DateTimeUtil;
import com.xbongbong.paas.toolbox.util.DateUtil;
import com.xbongbong.pro.product.pojo.vo.ChildProductVO;
import com.xbongbong.saas.constant.BasicConstant;
import com.xbongbong.saas.constant.ParameterConstant;
import com.xbongbong.saas.constant.StringConstant;
import com.xbongbong.saas.domain.dao.ProductUserDao;
import com.xbongbong.saas.domain.entity.ProductUserEntity;
import com.xbongbong.saas.domain.entity.UserAndDepTeamEntity;
import com.xbongbong.saas.model.ProductUserModel;
import org.apache.commons.collections4.CollectionUtils;
import org.elasticsearch.action.support.WriteRequest;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * @author haibin.zhang
 * @version v1.0
 * @date 2019/2/24 16:25
 * @since v1.0
 */
@Service
public class ProductUserModelImpl implements ProductUserModel {
    @Resource
    private ProductUserDao productUserDao;
    @Resource
    private PaasEsModel paasEsModel;
    @Resource
    private TransferSubFormHelper transferSubFormHelper;

    @Override
    public Integer insert(ProductUserEntity entity) throws XbbException {
        Integer result = productUserDao.insert(entity);
        PaasFormDataEntity paasFormDataEntity = transferSubFormHelper.transferUserAndDepTeamToFormData(IndexTypeEnum.IDX_SAAS_PRODUCT_TEAM, entity);
        InsertDTO saveDTO = paasEsModel.getSaveDTO(paasFormDataEntity, IndexTypeEnum.IDX_SAAS_PRODUCT_TEAM);
        paasEsModel.insert(saveDTO);
//        paasEsModel.insert(entity,IndexTypeEnum.IDX_SAAS_PRODUCT_TEAM,entity.getCorpid(),entity.getId(),entity.getDataId());
        return result;
    }

    @Override
    public Integer update(ProductUserEntity entity) throws XbbException {
        Integer result = productUserDao.update(entity);
        PaasFormDataEntity paasFormDataEntity = transferSubFormHelper.transferUserAndDepTeamToFormData(IndexTypeEnum.IDX_SAAS_PRODUCT_TEAM, entity);
        InsertDTO saveDTO = paasEsModel.getSaveDTO(paasFormDataEntity, IndexTypeEnum.IDX_SAAS_PRODUCT_TEAM);
        paasEsModel.update(saveDTO);
//        paasEsModel.update(entity,IndexTypeEnum.IDX_SAAS_PRODUCT_TEAM,entity.getCorpid(),entity.getId(),entity.getDataId());
        return result;
    }

    @Override
    public List<ProductUserEntity> findEntitys(Map<String, Object> param) {
        return productUserDao.findEntitys(param);
    }

    @Override
    public Integer getEntitysCount(Map<String, Object> param) {
        return productUserDao.getEntitysCount(param);
    }

    @Override
    public List findEntitysWithoutSub(Map<String, Object> param) {
        return null;
    }

    @Override
    public void inserBatch(List<ProductUserEntity> insetBatchList) throws XbbException{
        productUserDao.insertBatch(insetBatchList);
        List<PaasFormDataEntity> paasFormDataEntities = transferSubFormHelper.transferUserAndDepTeamToFormDataList(IndexTypeEnum.IDX_SAAS_PRODUCT_TEAM, insetBatchList);

        List<InsertDTO> insertDTOList = new ArrayList<>();
        for (PaasFormDataEntity paasFormDataEntity : paasFormDataEntities) {
            insertDTOList.add(paasEsModel.getSaveDTO(paasFormDataEntity, IndexTypeEnum.IDX_SAAS_PRODUCT_TEAM));
        }

//        for (ProductUserEntity productUserEntity : insetBatchList) {
//            InsertDTO insertDTO = new InsertDTO();
//            insertDTO.setWaitUntil(WriteRequest.RefreshPolicy.NONE);
//            insertDTO.setEsId(productUserEntity.getCorpid() + "_" + productUserEntity.getId());
//            insertDTO.setParent(productUserEntity.getCorpid() + "_" + productUserEntity.getDataId());
//            insertDTO.setSource(BeanUtil.convertBean2Map(productUserEntity, false, true));
//            insertDTO.setIndexTypeEnum(IndexTypeEnum.IDX_SAAS_PRODUCT_TEAM);
//            insertDTOList.add(insertDTO);
//        }
        paasEsModel.insertBatch(insertDTOList);
    }

    @Override
    public void updateBatch(List<ProductUserEntity> list, String corpid) throws XbbException{
        productUserDao.updateBatch(list,corpid);
        List<PaasFormDataEntity> paasFormDataEntities = transferSubFormHelper.transferUserAndDepTeamToFormDataList(IndexTypeEnum.IDX_SAAS_PRODUCT_TEAM, list);

        List<InsertDTO> insertList = new ArrayList<>();
        for (PaasFormDataEntity paasFormDataEntity : paasFormDataEntities) {
            insertList.add(paasEsModel.getSaveDTO(paasFormDataEntity, IndexTypeEnum.IDX_SAAS_PRODUCT_TEAM));
        }

//        for (ProductUserEntity productUserEntity : list){
//            InsertDTO insertDTO = new InsertDTO();
//            insertDTO.setWaitUntil(WriteRequest.RefreshPolicy.NONE);
//            insertDTO.setEsId(productUserEntity.getCorpid() + "_" + productUserEntity.getId());
//            insertDTO.setParent(productUserEntity.getCorpid() + "_" + productUserEntity.getDataId());
//            insertDTO.setSource(BeanUtil.convertBean2Map(productUserEntity, false, true));
//            insertDTO.setIndexTypeEnum(IndexTypeEnum.IDX_SAAS_PRODUCT_TEAM);
//            insertList.add(insertDTO);
//        }
        paasEsModel.updateBatch(insertList, WriteRequest.RefreshPolicy.NONE);
    }

    @Override
    public void deleteBatch(String corpid, List<Long> delIdList) throws XbbException{
        Map<String,Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        param.put("corpid",corpid);
        param.put("idIn",delIdList);
        List<ProductUserEntity> productUserEntityList = findEntitys(param);
        productUserDao.deleteBatch(corpid,delIdList);
        List<InsertDTO> updateBatch = new ArrayList<>();
        for (ProductUserEntity entity : productUserEntityList){
            InsertDTO insertDTO = new InsertDTO();
            insertDTO.setEsId(IndexTypeEnum.IDX_SAAS_PRODUCT_TEAM.getType() + "_" + corpid + "_" + entity.getId());
            insertDTO.setParent(corpid + "_" + entity.getDataId());
            Map<String, Object> map = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            map.put(StringConstant.DEL, DelEnum.DELETE.getDel());
            map.put(StringConstant.UPDATE_TIME, DateTimeUtil.getInt());
            insertDTO.setSource(map);
            insertDTO.setIndexTypeEnum(IndexTypeEnum.IDX_SAAS_PRODUCT_TEAM);
            updateBatch.add(insertDTO);
        }
        paasEsModel.updateBatch(updateBatch);
    }

    @Override
    public void batchDel(String corpid, List<Long> delIdList, List<ProductUserEntity> productUserEntities) throws XbbException{
        productUserDao.deleteBatch(corpid,delIdList);
        List<InsertDTO> updateBatch = new ArrayList<>();
        for (ProductUserEntity entity : productUserEntities){
            InsertDTO insertDTO = new InsertDTO();
            insertDTO.setEsId(IndexTypeEnum.IDX_SAAS_PRODUCT_TEAM.getType() + "_" + corpid + "_" + entity.getId());
            insertDTO.setParent(corpid + "_" + entity.getDataId());
            Map<String, Object> map = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            map.put(StringConstant.DEL, DelEnum.DELETE.getDel());
            map.put(StringConstant.UPDATE_TIME, DateTimeUtil.getInt());
            insertDTO.setSource(map);
            insertDTO.setIndexTypeEnum(IndexTypeEnum.IDX_SAAS_PRODUCT_TEAM);
            updateBatch.add(insertDTO);
        }
        paasEsModel.updateBatch(updateBatch);
    }

    /**
     * @param productId 产品id
     * @param corpid    公司id
     * @description: 建立产品全公司关系
     * @author: GuoJun.HU
     * @date: 2017/11/13 19:14
     * @modify:
     * @version:
     */
    @Override
    public void refreshProductUser(SaasFormSaveDTO saasFormSaveDTO, Long productId, String corpid, List<Object> visbleDept, List<Object> visbleUser) throws XbbException {
        Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        param.put(ParameterConstant.CORPID, corpid);
        param.put(ParameterConstant.DEL, 0);
        param.put(ParameterConstant.PRODUCT_ID, productId);
        Long now = DateTimeUtil.getInt();
        List<ProductUserEntity> productUserList = findEntitys(param);
        List<ProductUserEntity> visbleUserList = new ArrayList<>();
        List<ProductUserEntity> visbleDeptList = new ArrayList<>();
        for(ProductUserEntity productUserEntity : productUserList){
            if(Objects.equals(productUserEntity.getType(),BasicConstant.ZERO)){
                visbleUserList.add(productUserEntity);
            }else if(Objects.equals(productUserEntity.getType(),BasicConstant.ONE)){
                visbleDeptList.add(productUserEntity);
            }
        }
        insertRelationId(saasFormSaveDTO,visbleUser,visbleUserList,productId,corpid,now,BasicConstant.ZERO);
        insertRelationId(saasFormSaveDTO,visbleDept,visbleDeptList,productId,corpid,now,BasicConstant.ONE);
    }

    private void insertRelationId(SaasFormSaveDTO saasFormSaveDTO, List<Object> visbleUser,List<ProductUserEntity> productUserList,Long productId,String corpid,Long now,Integer type) throws XbbException{
        List<Object> relationIdList = new ArrayList<>();
        List<Object> copyOldRelationIdList = new ArrayList<>();
        Map<String,List<ProductUserEntity>> relationMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        List<ProductUserEntity> productUserEntityList;
        for(ProductUserEntity productUser : productUserList){
            relationIdList.add(productUser.getRelationId());
            copyOldRelationIdList.add(productUser.getRelationId());
            productUserEntityList = Objects.isNull(relationMap.get(productUser.getRelationId())) ? new ArrayList<>() : relationMap.get(productUser.getRelationId());
            productUserEntityList.add(productUser);
            relationMap.put(productUser.getRelationId(), productUserEntityList);
        }
        List<Object> visbleStringUser = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(visbleUser)) {
            for (Object obj : visbleUser) {
                visbleStringUser.add(obj.toString());
            }
            visbleUser = visbleStringUser;
        }
        ChildProductVO childProductVO = saasFormSaveDTO.getChildProductVO() == null ? new ChildProductVO() : saasFormSaveDTO.getChildProductVO();
        List<Long> addIdList = childProductVO.getAddIdList();
        List<Long> editIdList = childProductVO.getEditIdList();
        List<Long> delIdList = childProductVO.getDelIdList();
        List<ProductUserEntity> insertList = new ArrayList<>();
        List<Long> deleteList = new ArrayList<>();
        ProductUserEntity productUserEntity;
        if(null != visbleUser){
            //visbleUser 是选择的可见的人 或可见的部门,productUserList 是从数据库里查询出来的可见人或部门实体集合,这里是考虑关联表在保存后存入可见人或可见部门
            if(saasFormSaveDTO.getIsNew()) {
                for (Object object : visbleUser) {
                    productUserEntity = new ProductUserEntity();
                    productUserEntity.setCorpid(corpid);
                    productUserEntity.setParentId(0L);
                    productUserEntity.setDataId(productId);
                    productUserEntity.setRelationId(object.toString());
                    productUserEntity.setType(type);
                    insertList.add(productUserEntity);
                    if (CollectionUtils.isNotEmpty(addIdList)) {
                        for (Long addId : addIdList) {
                            productUserEntity = new ProductUserEntity();
                            productUserEntity.setCorpid(corpid);
                            productUserEntity.setParentId(productId);
                            productUserEntity.setDataId(addId);
                            productUserEntity.setRelationId(object.toString());
                            productUserEntity.setType(type);
                            insertList.add(productUserEntity);
                        }
                    }

                }
            }else {
                copyOldRelationIdList.retainAll(visbleUser);
                relationIdList.removeAll(copyOldRelationIdList);
                visbleUser.removeAll(copyOldRelationIdList);
                // 删掉的
                if(CollectionsUtil.isNotEmpty(relationIdList)){
                    for(Object object : relationIdList){
                        productUserEntityList = relationMap.get(String.valueOf(object));
                        productUserEntityList.forEach(userEntity -> deleteList.add(userEntity.getId()));
                    }
                    deleteByParentIdInAndRelationIdIn(corpid, Collections.singletonList(productId), relationIdList, type,deleteList);
                }
                // 新加的
                if(CollectionsUtil.isNotEmpty(visbleUser)){
                    for(Object object : visbleUser){
                        productUserEntity = new ProductUserEntity();
                        productUserEntity.setCorpid(corpid);
                        productUserEntity.setDataId(productId);
                        productUserEntity.setParentId(0L);
                        productUserEntity.setRelationId(object.toString());
                        productUserEntity.setType(type);
                        insertList.add(productUserEntity);
                        if (CollectionUtils.isNotEmpty(addIdList)) {
                            for (Long addId : addIdList) {
                                productUserEntity = new ProductUserEntity();
                                productUserEntity.setCorpid(corpid);
                                productUserEntity.setParentId(productId);
                                productUserEntity.setDataId(addId);
                                productUserEntity.setRelationId(object.toString());
                                productUserEntity.setType(type);
                                insertList.add(productUserEntity);
                            }
                        }
                       if (CollectionUtils.isNotEmpty(editIdList)) {
                           for (Long editId : editIdList) {
                               productUserEntity = new ProductUserEntity();
                               productUserEntity.setCorpid(corpid);
                               productUserEntity.setParentId(productId);
                               productUserEntity.setDataId(editId);
                               productUserEntity.setRelationId(object.toString());
                               productUserEntity.setType(type);
                               insertList.add(productUserEntity);
                           }
                       }

                    }
                }
                // 不变的
                if(CollectionsUtil.isNotEmpty(copyOldRelationIdList)) {
                    for(Object object : copyOldRelationIdList){
                        if (CollectionUtils.isNotEmpty(addIdList)) {
                            for (Long addId : addIdList) {
                                productUserEntity = new ProductUserEntity();
                                productUserEntity.setCorpid(corpid);
                                productUserEntity.setParentId(productId);
                                productUserEntity.setDataId(addId);
                                productUserEntity.setRelationId(object.toString());
                                productUserEntity.setType(type);
                                insertList.add(productUserEntity);
                            }
                        }
                    }
                    if (CollectionUtils.isNotEmpty(delIdList)) {
                        deleteByProductIdInAndRelationIdIn(corpid, delIdList, copyOldRelationIdList, type);
                    }
                }
            }

            if (CollectionsUtil.isNotEmpty(insertList)) {
                inserBatch(insertList);
            }
        }
    }

    @Override
    public List<UserAndDepTeamEntity> findBaseEntitys(Map<String, Object> map) {
        return productUserDao.findBaseEntitys(map);
    }

    @Override
    public ProductUserEntity getByKey(Long teamUserId, String corpid) {
        return productUserDao.getByKey(teamUserId,corpid);
    }

    @Override
    public void delete(ProductUserEntity productUserEntity) throws XbbException{
        productUserEntity.setDel(1);
        productUserEntity.setUpdateTime((long) DateUtil.getInt());
        productUserDao.update(productUserEntity);
        paasEsModel.delete(productUserEntity.getId(), productUserEntity.getCorpid(), IndexTypeEnum.IDX_SAAS_PRODUCT_TEAM,productUserEntity.getDataId());
    }

    @Override
    public Integer deleteByParentIdInAndRelationIdIn(String corpid, List<Long> parentIdIn, List<Object> relationIdIn, Integer type,List<Long> deleteList) throws XbbException {
        Map<String,Object> map = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        map.put(StringConstant.CORPID,corpid);
        map.put("type",type);
        map.put("relationIdIn",relationIdIn);
        map.put(StringConstant.DEL,DelEnum.NORMAL.getDel());
        map.put("parentIdIn",parentIdIn);
        List<UserAndDepTeamEntity> skuUserList = productUserDao.findBaseEntitys(map);
        skuUserList.forEach(item -> deleteList.add(item.getId()));
        deleteBatch(corpid,deleteList);
        return 1;
    }

    @Override
    public Integer deleteByParentIdInAndRelationIdInByScript(List<Long> parentIdIn, List<Object> relationIdIn, Integer type,List<Long> deleteList) throws XbbException {
        Map<String,Object> map = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        map.put("type",type);
        map.put("relationIdIn",relationIdIn);
        map.put(StringConstant.DEL, DelEnum.NORMAL.getDel());
        map.put("parentIdIn",parentIdIn);
        List<UserAndDepTeamEntity> skuUserList = productUserDao.findBaseEntitys(map);
        skuUserList.forEach(item -> deleteList.add(item.getId()));
        if (skuUserList.isEmpty()) {
            return 1;
        }
        productUserDao.deleteBatchByScript(deleteList);
        List<InsertDTO> updateBatch = new ArrayList<>();
        for (UserAndDepTeamEntity entity : skuUserList){
            InsertDTO insertDTO = new InsertDTO();
            insertDTO.setEsId(IndexTypeEnum.IDX_SAAS_PRODUCT_TEAM.getType() + "_" + entity.getCorpid() + "_" + entity.getId());
            insertDTO.setParent(entity.getCorpid() + "_" + entity.getDataId());
            Map<String, Object> map1 = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            map1.put(StringConstant.DEL, DelEnum.DELETE.getDel());
            map1.put(StringConstant.UPDATE_TIME, DateTimeUtil.getInt());
            insertDTO.setSource(map1);
            insertDTO.setIndexTypeEnum(IndexTypeEnum.IDX_SAAS_PRODUCT_TEAM);
            updateBatch.add(insertDTO);
        }
        paasEsModel.updateBatch(updateBatch);
        return 1;
    }

    @Override
    public Integer deleteByProductIdInAndRelationIdIn(String corpid, List<Long> productIdIn, List<Object> relationIdIn, Integer type) throws XbbException {
        return productUserDao.deleteByProductIdInAndRelationIdIn(corpid, productIdIn, relationIdIn, type);
    }
}
